之前在 Day14 示範過使用 Maplibre Style 新增兩個圖層,在前端呈現簡單的樣式。不過相信在前幾天的範例中,讀者應該也發現到屬性值可以不單純是數字或文字,而是包含在 JSON Array 內的各種表達式。
表達式的說明文件被紀錄在 expressions 一節。在 layers
的各個圖層中,被包含在 layout
和 paint
內的屬性值都適用表達式,用以更加靈活的適用不同狀況,例如:
表達式都是以 JSON Array 的型式存在,並在第一個元素賦予關鍵字。以下就來介紹幾個常用的表達式,並搭配實際範例:
可以使用 get
, has
, id
等關鍵字來取得或比較物件屬性,例如下面要決定圓圈顏色的表達式中:
{
"circle-color": [
"rgb",
// red is higher when feature.properties.temperature is higher
["get", "temperature"],
// green is always zero
0,
// blue is higher when feature.properties.temperature is lower
["-", 100, ["get", "temperature"]]
]
}
["get", "temperature"]
即代表取得物件 temperature
的屬性值,而 ["-", 100, ["get", "temperature"]]
則可以拆成兩部分來看:
["-", 100, X]
: 100 - XX=["get", "temperature"]
: X=temperature因此可以知道,其涵意是 100-溫度值。
而最外層由 rgb
開頭的 Array 也不難懂。雖然我們還沒學到該關鍵字,但後面接上三個表達式,很明顯就是要決定 RGB 值。所以上面範例中的圓圈值,一般來說就是 rgb(溫度,0,100-溫度)
的意思。(所以溫度為100時,顏色應該是暗紅色)
根據地圖的相機伸縮,Maplibre Style 會利用不同的 zoom
值來決定屬性。["zoom"]
這個表達式可以取得目前的縮放層級。
舉例來說,若我們需要依不同縮放層級調整圓圈大小,則可以使用:
{
"circle-radius": [
"interpolate", ["linear"], ["zoom"],
// zoom is 5 (or less) -> circle radius will be 1px
5, 1,
// zoom is 10 (or greater) -> circle radius will be 5px
10, 5
]
}
在使用關鍵字 interpolate
的情況下,圓圈半徑以設定的區間線性變化。從上面的設定來說,在 zoom=5 到 zoom=10 這個區間,其值會由 1px 線性變化到 5px,而超出區間的數值則保持不變。因此,我們可以用表格來表示半徑的變化:
zoom | 半徑 |
---|---|
... | 1 |
4 | 1 |
5 | 1 |
6 | 1.8 |
7 | 2.6 |
8 | 3.4 |
9 | 4.2 |
10 | 5 |
11 | 5 |
12 | 5 |
... | 5 |
渲染結果如下,可以看到隨著縮放層級的增加,紅色的圓圈也逐漸變大,非常符合直覺:
用不同關鍵字新增判斷邏輯,只要有點其它程式語言的概念,應該不難理解。例如,以下的關鍵字用於回傳布林值:
!
!=
<
<=
==
>
>=
舉例來說: ["<=", 1, 2]
會等同於 (1 <= 2),因此會回傳 false
。
而條件式就有各種參數了。case
表達式提供 if/then/else 的邏輯。而 match
則類似於其它語言中的 switch
,可以為各種輸入值指定回傳值,並給定預設值。條件式可使用以下的關鍵字:
all
所有參數都為 true
才會回傳 true
,例如:["all", ["==", 1, 1], [">", 3, 1]]
會回傳 true
any
任一參數為 true
就會回傳 true
case
兩個參數為一組case,若前一個參數回傳 true
則回傳下一個參數。若所有組別都回傳 false
,則使用預設值(最後一個參數)。例如:
["case",
["==" ["get", "gender"], "male"], "男生", <----一組case
["==" ["get", "gender"], "female"], "女生", <----一組case
"性別不明" <----預設值
]
會依物件的 gender
屬性來返回 男生
, 女生
, 性別不明
等三個值。
match
和 case
的差別在於,第一個參數是輸入值,用以和兩個一組的參數進行比對。因此上面的例子可以改寫為:
["match",
["get", "gender"], <----輸入值
"male", "男生", <----一組 match
"female", "女生", <----一組 match
"性別不明" <----預設值
]
其它還有 whthin
(用於比對地圖上的相對位置) 和 coalesce
等條件式,不過先掌握上面幾個就很夠用了。
簡單來說,Maplibre Style Expression 就是要使用 JSON 格式來模擬常用程式語言中的函式和各種運算符號。因此許多想得到想不到的關鍵字都可以在說明頁面中找到。
例如數學符號的 abs
, +
, -
, *
, /
、字串的操作 concat
, downcase
, upcase
等。使用者沒必要全部記住,只要在需要使用時查閱文件即可,在此就不一一列舉。
表達式在使用上相當接近 lisp 的括號表達式,它們對 Style 中各種屬性的運算,也有點像 SASS 與 CSS 的關係。
透過表達式,製圖者可以為渲染結果做出更多精細控制,讓畫面上更加協調。也因此會需要向量圖磚中,各種物件的屬性來搭配才能發揮威力。所以在製作專門用途的地圖時, tile schema 和 Style 的設計會需要互相考量,依需求持續進行調整。